package com.haixiaoke.saas.enterprise.contract.controller;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.haixiaoke.saas.auth.ali.service.AliAuthService;
import com.haixiaoke.saas.common.annotation.Log;
import com.haixiaoke.saas.common.annotation.RepeatSubmit;
import com.haixiaoke.saas.common.annotation.TenantScope;
import com.haixiaoke.saas.common.constant.ContractConstants;
import com.haixiaoke.saas.common.constant.HouseConstants;
import com.haixiaoke.saas.common.constant.OrderConstants;
import com.haixiaoke.saas.common.constant.TenantConstants;
import com.haixiaoke.saas.common.core.domain.AjaxResult;
import com.haixiaoke.saas.common.core.page.TableDataInfo;
import com.haixiaoke.saas.common.enums.BillStateEnum;
import com.haixiaoke.saas.common.enums.BusinessType;
import com.haixiaoke.saas.common.enums.OrderStateEnum;
import com.haixiaoke.saas.common.exception.ServiceException;
import com.haixiaoke.saas.common.tenant.TenantContext;
import com.haixiaoke.saas.common.utils.ExportUtil;
import com.haixiaoke.saas.contract.domain.LesseeContract;
import com.haixiaoke.saas.contract.domain.Proprietor;
import com.haixiaoke.saas.contract.service.ILesseeContractService;
import com.haixiaoke.saas.contract.service.IProprietorService;
import com.haixiaoke.saas.department.domain.ElectronicVisa;
import com.haixiaoke.saas.department.service.IElectronicVisaService;
import com.haixiaoke.saas.house.domain.House;
import com.haixiaoke.saas.house.service.IHouseService;
import com.haixiaoke.saas.order.domain.Order;
import com.haixiaoke.saas.order.service.IOrderService;
import com.haixiaoke.saas.system.BaseController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.math.BigDecimal;
import java.util.List;

/**
 * 租客合同Controller
 *
 * @author panda
 * @date 2024-06-04
 */
@RestController
@RequestMapping("/enterprise/contract/lesseeContract")
public class EnterpriseLesseeContractController extends BaseController {
    @Autowired
    private ILesseeContractService lesseeContractService;
    @Autowired
    private AliAuthService aliAuthService;
    @Autowired
    private IOrderService orderService;
    @Autowired
    private IElectronicVisaService electronicVisaService;
    @Autowired
    private IHouseService houseService;
    @Autowired
    private IProprietorService proprietorService;

    /**
     * 查询租客合同列表
     */
    @PreAuthorize("@ss.hasPermi('enterprise:lesseeContract:list')")
    @GetMapping("/list")
    public TableDataInfo list(LesseeContract lesseeContract) {
        startPage();
        List<LesseeContract> list = lesseeContractService.selectLesseeContractList(lesseeContract);
        return getDataTable(list);
    }

    /**
     * 导出租客合同列表
     */
    @PreAuthorize("@ss.hasPermi('enterprise:lesseeContract:export')")
    @Log(title = "租客合同", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public ResponseEntity<byte[]> export(HttpServletResponse response, LesseeContract contract) {
        LesseeContract lesseeContract = lesseeContractService.selectLesseeContractById(contract.getLesseeContractId());
        if (ObjectUtil.isEmpty(lesseeContract) || ContractConstants.CONTRACT_TYPE_ELECTRONIC.equals(lesseeContract.getContractType())) {
            throw new ServiceException("合同不存在或非电子合同，无法导出");
        }

        // 创建一个空的Word文档
        try {

            byte[] documentBytes = ExportUtil.generateWordDocument(lesseeContract.getContractContent());
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
            headers.setContentDispositionFormData("attachment", "formatted_document.docx");
            headers.setContentLength(documentBytes.length);

            return new ResponseEntity<>(documentBytes, headers, HttpStatus.OK);
        } catch (Exception e) {
            throw new ServiceException("导出失败：" + e.getMessage());
        }
    }

    /**
     * 获取租客合同详细信息及附属数据
     */
    @PreAuthorize("@ss.hasPermi('enterprise:lesseeContract:query')")
    @GetMapping(value = "/getAll/{lesseeContractId}")
    public AjaxResult getAllInfo(@PathVariable("lesseeContractId") String lesseeContractId) {
        return success(lesseeContractService.selectLesseeContractByLesseeContractId(lesseeContractId));
    }

    /**
     * 查询房屋的业主属性,获取电子合同模板名称前缀
     */
    @GetMapping(value = "/getTemplateNameByHouse/{houseId}")
    public AjaxResult getTemplateNameByHouse(@PathVariable("houseId") String houseId) {
        House house = houseService.selectHouseById(houseId);
        if (ObjectUtil.isNotEmpty(house)) {
            String templateName = "甲方企业";
            if (StrUtil.equals(HouseConstants.COOPERATION_TYPE_AGENCY_SERVICE, house.getCooperationType())) {
                Proprietor proprietor = proprietorService.selectProprietorByConUserId(house.getProprietorUserId());
                if (StrUtil.equals(ContractConstants.PROPRIETOR_TYPE_PERSON, proprietor.getProprietorType())) {
                    templateName = "甲方个人";
                }

            }
            return success(templateName);
        }
        return success();
    }

    /**
     * 获取租客合同详细信息
     */
    @PreAuthorize("@ss.hasPermi('enterprise:lesseeContract:query')")
    @GetMapping(value = "/{lesseeContractId}")
    public AjaxResult getInfo(@PathVariable("lesseeContractId") String lesseeContractId) {
        return success(lesseeContractService.selectLesseeContractById(lesseeContractId));
    }

    /**
     * 获取预览电子合同内容链接
     */
    @PreAuthorize("@ss.hasPermi('enterprise:lesseeContract:query')")
    @PostMapping(value = "/previewUrl")
    public AjaxResult electronicVisaPreviewUrl(@RequestBody LesseeContract lesseeContract) {
        return AjaxResult.success("操作成功", lesseeContractService.selectLesseeContractElectronicVisaPreviewUrl(lesseeContract));
    }

    /**
     * 新增租客合同
     */
    @PreAuthorize("@ss.hasPermi('enterprise:lesseeContract:add')")
    @Log(title = "租客合同", businessType = BusinessType.INSERT)
    @PostMapping
    @RepeatSubmit
    @TenantScope
    public AjaxResult add(@RequestBody @Valid LesseeContract lesseeContract) {
        lesseeContract.setTenantId(TenantContext.getTenantId());
        AjaxResult ajaxResult = this.checkContractParams(lesseeContract);
        if (ajaxResult != null) {
            return ajaxResult;
        }
        lesseeContract.setCreateBy(getUsername());
        return toAjax(lesseeContractService.insertLesseeContract(lesseeContract));
    }

    /**
     * 修改租客合同
     */
    @PreAuthorize("@ss.hasPermi('enterprise:lesseeContract:edit')")
    @Log(title = "租客合同", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody LesseeContract lesseeContract) {
        return toAjax(lesseeContractService.updateLesseeContract(lesseeContract));
    }

    /**
     * 合同撤销
     */
    @PreAuthorize("@ss.hasPermi('enterprise:lesseeContract:edit')")
    @Log(title = "租客合同撤销", businessType = BusinessType.UPDATE)
    @PutMapping("/repeal")
    public AjaxResult repeal(@RequestBody LesseeContract lesseeContract) {
        LesseeContract contract = lesseeContractService.selectLesseeContractById(lesseeContract.getLesseeContractId());
        if (ObjectUtil.isEmpty(contract)) {
            return error("合同不存在");
        }
        if (!(ContractConstants.LESSEE_CONTRACT_STATUS_UNCONFIRMED.equals(contract.getLesseeContractStatus()) ||
                ContractConstants.LESSEE_CONTRACT_STATUS_BE_SIGNING.equals(contract.getLesseeContractStatus()))) {
            return error("合同状态异常，请刷新后再试");
        }
        contract.setUpdateBy(getUsername());
        return toAjax(lesseeContractService.repealLesseeContract(contract));
    }

    /**
     * 上传确认合同
     *
     * @param lesseeContract
     * @return
     */
    @PreAuthorize("@ss.hasPermi('enterprise:lesseeContract:edit')")
    @Log(title = "租客合同上传确认合同", businessType = BusinessType.UPDATE)
    @PutMapping("/uploadContractImage")
    public AjaxResult uploadContractImage(@RequestBody LesseeContract lesseeContract) {
        lesseeContract.setUpdateBy(getUsername());
        return lesseeContractService.uploadContractImage(lesseeContract);
    }

    /**
     * 重新发起租客合同
     *
     * @param lesseeContract
     * @return
     */
    @PreAuthorize("@ss.hasPermi('enterprise:lesseeContract:edit')")
    @Log(title = "重新发起租客合同", businessType = BusinessType.UPDATE)
    @PostMapping("/relaunch")
    @RepeatSubmit
    @TenantScope
    public AjaxResult relaunch(@RequestBody LesseeContract lesseeContract) {
        lesseeContract.setTenantId(TenantContext.getTenantId());
        lesseeContract.getOrder().setOrderId(lesseeContract.getOrderId());
        AjaxResult ajaxResult = this.checkContractParams(lesseeContract);
        if (ajaxResult != null) {
            return ajaxResult;
        }
        LesseeContract contract = lesseeContractService.selectLesseeContractById(lesseeContract.getLesseeContractId());
        if (!(ContractConstants.LESSEE_CONTRACT_STATUS_TERMINATED.equals(contract.getLesseeContractStatus()) ||
                ContractConstants.LESSEE_CONTRACT_STATUS_OVERDUE.equals(contract.getLesseeContractStatus()))) {
            return error("合同状态不允许重新发起");
        }
        if (lesseeContractService.checkRelaunch(contract.getOrderId())) {
            return error("订单有进行中或签署完成的合同");
        }
        lesseeContract.setUpdateBy(getUsername());
        lesseeContract.setContractImage(null);
        lesseeContract.setUpdateTime(null);
        lesseeContract.setUpdateBy(null);
        lesseeContract.setCreateBy(getUsername());
        return toAjax(lesseeContractService.insertLesseeContract(lesseeContract));
    }

    /**
     * 签署合同
     */
    @PreAuthorize("@ss.hasPermi('enterprise:lesseeContract:signing')")
    @Log(title = "租客合同签署", businessType = BusinessType.UPDATE)
    @PutMapping("/signing")
    @TenantScope
    public AjaxResult lesseesSigning(@RequestBody LesseeContract lesseeContract) {
        lesseeContract.setTenantId(TenantContext.getTenantId());
        return lesseeContractService.signingLesseeContract(lesseeContract, false, null);
    }

    /**
     * 删除租客合同
     */
    @PreAuthorize("@ss.hasPermi('enterprise:lesseeContract:remove')")
    @Log(title = "租客合同", businessType = BusinessType.DELETE)
    @DeleteMapping("/{lesseeContractIds}")
    public AjaxResult remove(@PathVariable String[] lesseeContractIds) {
        return toAjax(lesseeContractService.deleteLesseeContractByLesseeContractIds(lesseeContractIds));
    }

    public AjaxResult checkContractParams(LesseeContract lesseeContract) {
        if (ContractConstants.CONTRACT_TYPE_ELECTRONIC.equals(lesseeContract.getContractType())) {
            House house = houseService.selectHouseById(lesseeContract.getHouseId());
            ElectronicVisa electronicVisa = electronicVisaService.selectElectronicVisaByCooperationType(house);
            if (ObjectUtil.isEmpty(electronicVisa)) {
                return error("电子签信息异常，请联系管理员办理");
            }
            if (ContractConstants.LESSEE_TYPE_PERSON.equals(lesseeContract.getLesseeType())) {
                Proprietor proprietor = proprietorService.selectProprietorByConUserId(house.getProprietorUserId());
                if (ObjectUtil.isNotEmpty(proprietor) && StrUtil.equals(proprietor.getCardNumber(), lesseeContract.getCardNumber())) {
                    return error("业主无需租赁自己的房间");
                }
            }
            if (TenantConstants.ELECTRONIC_VISA_TYPE_ENTERPRISE.equals(electronicVisa.getElectronicVisaType())
                    && electronicVisa.getContractLeftNumber() <= 0) {
                return error("电子合用余额不足,请购买电子合同用量");
            }
        }
        if (ObjectUtil.isEmpty(lesseeContract.getOrder())) {
            return warn("租住信息不能为空");
        }
        Order order = lesseeContract.getOrder();
        if (StrUtil.isNotEmpty(order.getOrderId())) {
            Order orderById = orderService.selectOrderById(order.getOrderId());
            if (ObjectUtil.isNotEmpty(orderById) &&
                    OrderStateEnum.ORDER_STATE_CANCEL.getValue().equals(orderById.getOrderState())) {
                return error("订单已作废，不可新增合同");
            }
        }
        if (StrUtil.isBlank(lesseeContract.getHouseId())) {
            return warn("请选择房间");
        }
        if (ObjectUtil.isNull(order.getCheckInTime()) || ObjectUtil.isNull(order.getCheckOutTime())) {
            return warn("居住周期不能为空");
        }
        // 入住时间在退房时间之后则退出
        if (order.getCheckInTime().after(order.getCheckOutTime())) {
            return warn("居住周期错误");
        }
        if (lesseeContract.getContractScanningList().size() > 30) {
            return warn("合同扫描件不能超过30张");
        }
        order.setHouseId(lesseeContract.getHouseId());
        if (orderService.checkRepeatOrder(order)) {
            return warn("房间在入住时间内已出租");
        }
        if (OrderConstants.RENTAL_MODE_MONTH.equals(order.getRentalMode())) {
            if (ObjectUtil.isNull(order.getDepositNumber()) || ObjectUtil.isNull(order.getPayNumber())) {
                return warn("请选择押付方式");
            }
            if (order.getDepositNumber() <= 0 || order.getPayNumber() <= 0) {
                return warn("押付方式错误");
            }
            if (order.getMonthRent().compareTo(BigDecimal.ZERO) <= 0) {
                return warn("月租金只能大于0");
            }
            if (order.getMonthRent().scale() > 2) {
                return warn("月租金小数点最多两位小数");
            }
            if (!ObjectUtil.isEmpty(order.getRentCollectionDate())) {
                if (OrderConstants.RENT_DAY_TYPE_DAY.equals(order.getRentDayType()) && order.getRentCollectionDate() < 0) {
                    return warn("收租日不能小于0");
                } else if (order.getRentCollectionDate() <= 0) {
                    return warn("收租日不能小于1");
                }

                if (order.getRentCollectionDate() > 31) {
                    return warn("收租日不能大于31");
                }
            }

            if (ObjectUtil.isEmpty(order.getBillGenerationDate()) || order.getBillGenerationDate() <= 0) {
                return warn("账单生成时间不能小于0");
            }

            if (order.getBillGenerationDate() > 31) {
                return warn("账单生成时间不能大于31天");
            }

        } else if (OrderConstants.RENTAL_MODE_DISPOSABLE.equals(order.getRentalMode())) {
            if (order.getDeposit().compareTo(BigDecimal.ZERO) <= 0) {
                return warn("押金只能大于0");
            }
            if (order.getDeposit().scale() > 2) {
                return warn("押金小数点最多两位小数");
            }
            if (order.getTotalRent().compareTo(BigDecimal.ZERO) <= 0) {
                return warn("总租金只能大于0");
            }
            if (order.getTotalRent().scale() > 2) {
                return warn("总租金小数点最多两位小数");
            }
        }
        if (CollectionUtil.isNotEmpty(lesseeContract.getContractFacilitiesItemList())) {
            // 判断房屋设施id、名称是否为空
            boolean facilitiesResult = lesseeContract.getContractFacilitiesItemList().stream()
                    .anyMatch(entry -> ObjectUtil.isEmpty(entry.getFacilitiesId()) || StrUtil.isBlank(entry.getFacilitiesName()));
            if (facilitiesResult) {
                return warn("房屋设施信息不能为空");
            }
            // 判断加房屋设施价格、数量
            boolean numberResult = lesseeContract.getContractFacilitiesItemList().stream()
                    .anyMatch(entry -> entry.getFacilitiesNumber() == null ||
                            entry.getFacilitiesNumber().compareTo(BigDecimal.ZERO) <= 0 ||
                            entry.getFacilitiesNumber().scale() > 0);
            if (numberResult) {
                return warn("房屋设施数量填写错误");
            }
            boolean housePriceBoolean = lesseeContract.getContractFacilitiesItemList().stream()
                    .anyMatch(entry -> entry.getFacilitiesPrice() == null || entry.getFacilitiesPrice().compareTo(BigDecimal.ZERO) <= 0);
            if (housePriceBoolean) {
                return warn("房屋设施价格只能大于0");
            }
            boolean priceBoolean = lesseeContract.getContractFacilitiesItemList().stream()
                    .anyMatch(entry -> entry.getFacilitiesPrice().scale() > 2);
            if (priceBoolean) {
                return warn("房屋设施价格小数点最多两位小数");
            }
        }
        if (ContractConstants.LESSEE_TYPE_PERSON.equals(lesseeContract.getLesseeType())) {
            if (ContractConstants.CONTRACT_TYPE_ENTERPRISE_PAPER.equals(lesseeContract.getContractType())) {
                return warn("合同类型不可为企业纸质合同，请重新选择合同类型");
            }
            if (!aliAuthService.identityCheck(lesseeContract.getContactName(), lesseeContract.getCardNumber())) {
                return warn("身份证信息不正确");
            }
        } else if (ContractConstants.LESSEE_TYPE_ENTERPRISE.equals(lesseeContract.getLesseeType())) {
            if (!ContractConstants.CONTRACT_TYPE_ENTERPRISE_PAPER.equals(lesseeContract.getContractType())) {
                return warn("合同类型非企业纸质合同，请选择企业纸质合同");
            }
        }
        if (CollectionUtil.isEmpty(lesseeContract.getHouseBillList())) {
            return warn("账单信息不能为空");
        }
        if (StrUtil.isEmpty(lesseeContract.getPenaltyStates())) {
            return warn("违约金生成状态不能为空");
        }
        if (BillStateEnum.PENALTY_STATES_COLLECT.getValue().equals(lesseeContract.getPenaltyStates())) {
            if (ObjectUtil.isNull(lesseeContract.getPenaltyScale())) {
                return warn("违约金比例不能为空");
            }
        }
        return null;
    }
}
